package cn.edu.hqu.pre;

import org.uma.jmetal.problem.permutationproblem.impl.AbstractIntegerPermutationProblem;
import org.uma.jmetal.solution.permutationsolution.PermutationSolution;

/**
 * 定义“历史文化体验旅游线路”问题
 *
 * @author 洪佳森
 * @date 2023-12-11
 */
public class HistoricalCulturalExperienceTourismRouteProblem extends AbstractIntegerPermutationProblem {

    /**
     * 距离矩阵
     */
    private double[][] distanceMatrix;

    /**
     * 时间矩阵
     */
    private double[][] travelTimeMatrix;

    /**
     * 游玩时间矩阵
     */
    private double[] playMatrix;


    @Override
    public int numberOfVariables() {
        return 22;
    }

    @Override
    public int numberOfObjectives() {
        return 3;
    }

    @Override
    public int numberOfConstraints() {
        return 0;
    }

    @Override
    public String name() {
        return "历史文化体验旅游线路";
    }

    @Override
    public PermutationSolution<Integer> evaluate(PermutationSolution<Integer> solution) {
        double fitness1 = 0.0;
        double fitness2 = 0.0;
        double fitness3 = 0.0;
        for (int i = 0; i < (numberOfVariables() - 1); i++) {
            int x = solution.variables().get(i);
            int y = solution.variables().get(i+1);

            fitness1 += distanceMatrix[x][y];
            fitness2 += travelTimeMatrix[x][y];
            fitness3 += playMatrix[x];
        }
        int firstCity = solution.variables().get(0);
        int lastCity = solution.variables().get(numberOfVariables() - 1);
        fitness1 += distanceMatrix[firstCity][lastCity];
        fitness2 += travelTimeMatrix[firstCity][lastCity];
        fitness3 += playMatrix[lastCity];

        solution.objectives()[0] = fitness1;
        solution.objectives()[1] = fitness2;
        solution.objectives()[2] = fitness3;

        return solution;
    }

    public void setDistanceMatrix(double[][] distanceMatrix) {
        this.distanceMatrix = distanceMatrix;
    }

    public void setTravelTimeMatrix(double[][] travelTimeMatrix) {
        this.travelTimeMatrix = travelTimeMatrix;
    }

    public void setPlayMatrix(double[] playMatrix) {
        this.playMatrix = playMatrix;
    }
}
